package com.igo.onepack;

import com.igo.onepack.channel.*;
import com.igo.onepack.utils.IOUtils;
import com.igo.onepack.utils.StringUtils;
import org.apache.commons.cli.*;

import java.io.*;
import java.util.List;
import java.util.Properties;

public class Main {

    private static final Options options = new Options();

    public static void main(String... args) throws ParseException, OnePackException {
        try {
            configOptions();
            CommandLineParser parser = new DefaultParser();
            CommandLine commandLine = parser.parse(options,args,false);
            if (commandLine.hasOption("version")) {
                version();
            } else {
                pack(commandLine);
            }
        } finally {
            System.exit(0);
        }
    }

    private static void pack(CommandLine cli) throws OnePackException {
        List<String> argList = cli.getArgList();
        int paraCount = argList.size();
        String apkName = paraCount > 0 ? argList.get(paraCount-1) : "";
        if (StringUtils.isEmpty(apkName)) {
            throw new OnePackException("apk file invalid");
        }
        ChannelConfig channelConfig = null;
        SignConfig signConfig = null;
        String outDir = null;
        boolean onlyPackChannel = false;
        boolean onlySign = false;
        if (cli.hasOption("onlyPackChannel")) {
            onlyPackChannel = true;
        }
        if (cli.hasOption("c") || cli.hasOption("channelConfig")) {
            channelConfig = parserChannelConfig(cli.getOptionValue("c"));
        }
        if (cli.hasOption("s") || cli.hasOption("signConfig")) {
            signConfig = parserSignConfig(cli.getOptionValue("s"));
        }
        if (cli.hasOption("o") || cli.hasOption("out")) {
            outDir = cli.getOptionValue("o");
        }
        if (cli.hasOption("onlySign")) {
            onlySign = true;
        }
        File apkFile = new File(apkName);
        if (StringUtils.isEmpty(outDir)) {
            String parent = apkFile.isAbsolute() ? apkFile.getParent() : System.getProperty("user.dir");
            outDir = createDefaultOutDir(parent);
        }
        OnePack onePack = new OnePack();
        onePack.setOnlyPackChannel(onlyPackChannel);
        onePack.setChannelConfig(channelConfig);
        onePack.setOnlySign(onlySign);
        onePack.setSignConfig(signConfig);
        onePack.setOutDir(new File(outDir));
        onePack.setOriginApkFile(apkFile);
        onePack.start();
    }

    private static void version() {
        System.out.println("onepack version \""+OnePack.getVersion()+"\"");
    }

    private static String createDefaultOutDir(String parent) {
        return parent + File.separator + "out";
    }

    private static SignConfig parserSignConfig(String signConfigFile) throws OnePackException {
        try {
            System.out.println(signConfigFile);
            Properties properties = getConfigProperties(signConfigFile);
            SignConfig signConfig = new SignConfig();
            signConfig.setKsPath(properties.getProperty("storeFile"));
            signConfig.setKsPass(properties.getProperty("storePassword"));
            signConfig.setKeyAlias(properties.getProperty("keyAlias"));
            signConfig.setKeyPass(properties.getProperty("keyPassword"));
            return signConfig;
        } catch (Exception e) {
            throw new OnePackException("sign config read failed.",e);
        }
    }

    private static ChannelConfig parserChannelConfig(String channelConfigFile) throws OnePackException {
        try {
            System.out.println(channelConfigFile);
            Properties properties = getConfigProperties(channelConfigFile);
            ChannelConfig channelConfig = new ChannelConfig();
            channelConfig.setKey(properties.getProperty("keyName"));
            String channel = properties.getProperty("channel");
            channelConfig.setChannels(channel.split(";"));
            return channelConfig;
        } catch (Exception e) {
            throw new OnePackException("channel config read failed.",e);
        }
    }

    private static Properties getConfigProperties(String configFile) throws IOException {
        InputStream is = null;
        try {
            is = new FileInputStream(configFile);
            Properties properties = new Properties();
            properties.load(is);
            return properties;
        } finally {
            IOUtils.closeQuietly(is);
        }
    }

    private static void configOptions() {
        Option versionOption = Option.builder("version").longOpt("version").desc("prints the version then exits").build();
        Option signConfigOption = Option.builder("s").longOpt("signConfig").hasArg(true).desc("config apk sign info").build();
        Option channelConfigOption = Option.builder("c").longOpt("channelConfig").hasArg(true).desc("config apk channel info").build();
        Option outDirOption = Option.builder("o").longOpt("out").desc("set onepack out dir").hasArg(true).build();
        //只需要打渠道包,跳过加固流程
        Option noChannelOption = Option.builder("onlyPackChannel").longOpt("onlyPackChannel").desc("only pack channel").hasArg(false).build();
        //只需要对未签名的Apk进行签名
        Option onlySign = Option.builder("onlySign").longOpt("onlySign").desc("Only sign apk").build();
        options.addOption(versionOption)
                .addOption(signConfigOption)
                .addOption(channelConfigOption)
                .addOption(outDirOption)
                .addOption(noChannelOption)
                .addOption(onlySign);
    }
}
